/**
 *
 */
package com.btkjgc.utils;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.context.ApplicationContext;

import java.util.List;

/**
 * @author Maple
 */
final public class HibernateUtil
{
	private static SessionFactory sessionFactory = null;

	static
	{
		ApplicationContext ac = ApplicationContextUtil.getApplicationContext();
		sessionFactory = (SessionFactory) ac.getBean("sessionFactory");
	}

	private HibernateUtil()
	{

	}

	public static void setSessionFactory(SessionFactory factory)
	{
		sessionFactory = factory;
	}

	public static SessionFactory getSessionFactory()
	{
		return sessionFactory;
	}

	public static Session openSession()
	{
		return sessionFactory.openSession();
	}

	@SuppressWarnings("rawtypes")
	public static Object getObjectById(Class clazz, java.io.Serializable id)
	{
		Session session = null;
		Object object = null;
		try
		{
			session = openSession();
			object = session.get(clazz, id);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
		return object;
	}

	public static void save(Object obj)
	{
		Session ss = null;
		Transaction tx = null;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			ss.save(obj);
			tx.commit();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
	}

	public static int saveIfNotExists(Object obj)
	{
		Session ss = null;
		Transaction tx = null;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			ss.save(obj);
			tx.commit();
		}
		catch (ConstraintViolationException e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			return Constant.UNKNOW_FAIL;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
		return Constant.SUCCESS;
	}

	public static void update(Object obj)
	{
		Session ss = null;
		Transaction tx = null;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			ss.update(obj);
			tx.commit();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
	}

	public static void updateIfExists(Object obj)
	{
		Session ss = null;
		Transaction tx = null;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			ss.update(obj);
			tx.commit();
		}
		catch (Exception e)
		{
			if (tx != null)
			{
				tx.rollback();
			}
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
	}

	public static void delete(Object obj)
	{
		Session ss = null;
		Transaction tx = null;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			ss.delete(obj);
			tx.commit();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
	}

	public static void saveOrUpdate(Object obj)
	{
		Session ss = null;
		Transaction tx = null;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			ss.saveOrUpdate(obj);
			tx.commit();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
	}

	@SuppressWarnings("rawtypes")
	public static List executeQuery(String hql, String[] parameters)
	{
		Session session = null;
		List list = null;
		try
		{
			session = openSession();
			Query query = session.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			list = query.list();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
		return list;
	}

	@SuppressWarnings("rawtypes")
	public static List executeHQLQuery(String hql, Object... parameters)
	{
		Session session = null;
		List list = null;
		try
		{
			session = openSession();
			Query query = session.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, String.valueOf(parameters[i]));
				}
			}
			list = query.list();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
		return list;
	}

	@SuppressWarnings("rawtypes")
	public static Object executeObjectLQuery(String hql, Object... parameters)
	{
		Session session = null;
		List list = null;
		try
		{
			session = openSession();
			Query query = session.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, String.valueOf(parameters[i]));
				}
			}
			list = query.list();
			if (list.size() > 0) { return list.get(0); }
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
		return null;
	}

	@SuppressWarnings("rawtypes")
	public static List executeSQLQuery(String hql, Object... parameters)
	{
		Session session = null;
		List list = null;
		try
		{
			session = openSession();
			Query query = session.createSQLQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i].toString());
				}
			}
			list = query.list();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
		return list;
	}

	@SuppressWarnings("rawtypes")
	public static List executeQuery(String hql, int pageIndex, int pageSize,
			String[] parameters)
	{
		Session session = null;
		List list = null;
		try
		{
			session = openSession();
			Query query = session.createQuery(hql);
			query.setFirstResult(pageIndex * pageSize);
			query.setMaxResults(pageSize);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			list = query.list();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
		return list;
	}

	public static int getInt(String hql, Object... parameters)
	{
		Session session = null;
		try
		{
			session = openSession();
			Query query = session.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i].toString());
				}
			}
			return ((Number) (query.uniqueResult())).intValue();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
	}

	public static int executeCountQuery(String hql, String[] parameters)
	{
		Session session = null;
		try
		{
			session = openSession();
			Query query = session.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			return ((Number) (query.uniqueResult())).intValue();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
	}

	@SuppressWarnings("rawtypes")
	public static List executeQueryFinalNRecords(String hql,
			String[] parameters, Integer record_length)
	{
		Session session = null;
		List list = null;
		try
		{
			session = openSession();
			Query query = session.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			query.setMaxResults(record_length);
			list = query.list();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
		return list;
	}

	public static void executeUpdate(String hql, String[] parameters)
	{
		Session ss = null;
		Transaction tx = null;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			Query query = ss.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			query.executeUpdate();
			tx.commit();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
	}

	public static void executeSQLUpdate(String hql, Object... parameters)
	{
		Session ss = null;
		Transaction tx = null;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			Query query = ss.createSQLQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					if (parameters[i] != null)
					{
						query.setString(i, parameters[i].toString());
					}
					else
					{
						query.setString(i, null);
					}
				}
			}
			query.executeUpdate();
			tx.commit();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
	}

	public static int executeUpdateIfExist(String hql, String[] parameters)
	{
		Session ss = null;
		Transaction tx = null;
		int updateNumbers = 0;
		try
		{
			ss = openSession();
			tx = ss.beginTransaction();
			Query query = ss.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			updateNumbers = query.executeUpdate();
			tx.commit();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (tx != null)
			{
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
		return updateNumbers;
	}

	public static Object objectQuery(String hql, String[] parameters)
	{
		Session ss = null;
		Object obj = null;
		try
		{
			ss = openSession();
			Query query = ss.createQuery(hql);

			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			obj = query.uniqueResult();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
		return obj;
	}

	public static Object objectLatestQuery(String hql, String parameters[])
	{
		Session ss = null;
		Object obj = null;
		try
		{
			ss = openSession();
			Query query = ss.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			query.setFirstResult(0);
			query.setMaxResults(1);
			obj = query.uniqueResult();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (ss != null && ss.isOpen())
			{
				ss.close();
			}
		}
		return obj;
	}

	@SuppressWarnings("rawtypes")
	public static Object[] sumQuery(String hql, String parameters[])
	{
		// Creat by Rong on 2015-6-27
		Session session = null;
		List list = null;
		try
		{
			session = HibernateUtil.openSession();
			Query query = session.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			list = query.list();
			if (list.size() > 0)
			{
				return (Object[]) list.get(0);
			}
			else
			{
				return null;
			}

		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
	}

	@SuppressWarnings("rawtypes")
	public static List selectQuery(String hql)
	{
		// 直接执行sql，直接执行在数据库可以执行的sql（相当于不使用映射文件）
		// Creat by Rong on 2015-6-27
		Session session = null;
		List list = null;
		try
		{
			session = HibernateUtil.openSession();
			Query query = session.createSQLQuery(hql);
			/*
			 * if (parameters != null && parameters.length > 0) { for (int i =
			 * 0; i < parameters.length; i++) { query.setString(i,
			 * parameters[i]); } }
			 */
			list = query.list();
			return list;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
	}

	@SuppressWarnings({ "unused", "rawtypes" })
	public List findColumnByPage(String hql, String parameters[])
	{
		// Creat by Rong on 2015-8-8
		Session session = null;
		List list = null;
		try
		{
			session = HibernateUtil.openSession();
			Query query = session.createQuery(hql);
			if (parameters != null && parameters.length > 0)
			{
				for (int i = 0; i < parameters.length; i++)
				{
					query.setString(i, parameters[i]);
				}
			}
			query.setFirstResult(0);
			query.setMaxResults(1);
			return query.list();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
	}

	public static Integer updateQuery(String hql)
	{
		// 直接执行sql，直接执行在数据库可以执行的sql（相当于不使用映射文件）
		// Creat by Rong on 2015-9-1
		Session session = null;
		try
		{
			session = HibernateUtil.openSession();
			Query query = session.createSQLQuery(hql);
			return query.executeUpdate();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			if (session != null && session.isOpen())
			{
				session.close();
			}
		}
	}

}
